﻿using System;

namespace PhantomDb.Config
{
    public abstract class AbstractConfigurator
    {

        protected abstract Configuration.Phantom GetSection();
        protected abstract void Save(PhantomDb.Core.Environment e);

        public virtual string ParseConnectionString(string connection)
        {
            string result = connection;
            result = result.Replace("$(current_dir)", Environment.CurrentDirectory);
            result = result.Replace("$(app_data)", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
            return result;
        }

        public void Configure(string path = null)
        {
            //HttpContext.Current.Application

            //1 - Try and get the section 
            var phantomSection = GetSection();

            if ((phantomSection == null) ||
                !phantomSection.ElementInformation.IsPresent)
            {
                throw new Exception("PhantomDv.MVC configuration error.");
            }

            var environment = new PhantomDb.Core.Environment();

            foreach (Configuration.Schema schemaSection in phantomSection.Schemas)
            {
                string name = schemaSection.Name;
                string context = schemaSection.Context;
                string handler = schemaSection.Handler;
                string connection = schemaSection.Connection;

                connection = ParseConnectionString(connection);

                if (string.IsNullOrWhiteSpace(handler))
                {
                    throw new System.Configuration.ConfigurationErrorsException("Error, the database handler can't be null or empty.");
                }

                var schema = new PhantomDb.Core.Schema(name);
                var ctxType = context.ToLower().Equals("generic") ? typeof(PhantomDb.Core.GenericContext) : Type.GetType(context);
                var hndType = Type.GetType(handler);

                if (ctxType == null)
                {
                    throw new Exception("No se ha podido generar el contexto " + context);
                }

                if (hndType == null)
                {
                    throw new Exception("No se ha podido generar el manejador " + handler);
                }

                schema.Context = Activator.CreateInstance(ctxType) as PhantomDb.Core.IContext;
                schema.Handler = Activator.CreateInstance(hndType) as DataBaseHandler;
                schema.Handler.Connection = connection;
                schema.Handler.TraceSql = schemaSection.TraceSql;

                if (!string.IsNullOrWhiteSpace(schemaSection.TraceFormat))
                {
                    schema.Handler.TraceFormat = schemaSection.TraceFormat;
                }

                schema.Generate();

                environment.Add(schema);
            }

            Save(environment);
        }
    }
}
